package com.ruoyi.web.controller.app;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.sign.DecryptData;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.domain.WxLoginAuto;
import com.ruoyi.system.domain.xcx.*;
import com.ruoyi.system.service.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 小程序移动端通用接口
 */
@RestController
@RequestMapping("/applet")
public class AppletController extends BaseController {

    // 令牌有效期（默认三个月）
    @Value("${token.appexpireTime}")
    private int appexpireTime;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IAppUserHistoryService appUserHistoryService;
    @Autowired
    private IDouyinBasicmemberPriceService douyinBasicmemberPriceService;

    //private static  final String YUMING="https://admin.pinkeyuan.cn/api/openapi";
    private static  final String YUMING="http://localhost:8080/api/openapi";

    /**
     * 微信小程序授权登录验证
     *
     * @param wxLoginAuto 登录信息
     * @return 结果
     */
    @GetMapping("/wxlogin")
    public AjaxResult wxlogin(WxLoginAuto wxLoginAuto) throws Exception {
        if (StringUtils.isEmpty(wxLoginAuto.getCode())) {
            return error("code不能为空");
        }
        AjaxResult ajax = AjaxResult.success();

        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + wxLoginAuto.getAplUuid());
        if(StringUtils.isNull(douyinApl)){
            return error("应用不存在");
        }

        // 生成令牌
        String appId = douyinApl.getXcxAppId();
        String appSecret = douyinApl.getXcxAppSecret();
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + wxLoginAuto.getCode() + "&grant_type=authorization_code";
        logger.info("请求地址Referer：{}", url);
        JSONObject sessionInfo = JSONObject.parseObject(HttpUtils.sendGet(url)); // 调用微信接口获取 session_key 和 openid
        logger.info("微信授权返回信息为{}", sessionInfo);
        if (StringUtils.isNull(sessionInfo)) {
            return error("微信授权信息返回为空");
        }
        String openId = sessionInfo.getString("openid");
       // String sessionKey = sessionInfo.getString("session_key");
        AppUser appUser = appUserService.selectAppUserByOpenId(openId);
        //String encryptedData=wxLoginAuto.getEncryptedData();
        //String iv=wxLoginAuto.getIv();
       // JSONObject jSONObject= DecryptData.decryptData(sessionKey,encryptedData,iv);
        int flag = 0;
        if (StringUtils.isNull(appUser)) {
            AppUser appUserNew = new AppUser();
            appUserNew.setOpenid(openId);
            appUserNew.setLoginTime(new Date());
            appUserNew.setCreateTime(new Date());
            appUserNew.setRole("3");
            if(!appUser.getRole().equals("3")){
                appUserNew.setFatherId(wxLoginAuto.getFatherId()==null?"":wxLoginAuto.getFatherId());
            }
            appUserNew.setAplUuid(wxLoginAuto.getAplUuid());
           // appUserNew.setNickname(jSONObject.getString("nickName"));
            //appUserNew.setGender(Integer.parseInt(jSONObject.get("gender").toString()));
            appUserNew.setLoginIp(AddressUtils.getRealAddressByIP(IpUtils.getIpAddr()));
            flag = appUserService.insertAppUser(appUserNew);
            if (flag > 0) {
                appUser = appUserService.selectAppUserByOpenId(openId);
            } else {
                return error("授权异常");
            }
        }
        redisCache.setCacheObject(Constants.XCX_TOKEN + openId, appUser, appexpireTime, TimeUnit.MINUTES);
        ajax.put(Constants.XCX_TOKEN, openId);
        return ajax;
    }
    /**
     * 修改用户信息
     *
     * @param appUser 登录信息
     * @return 结果
     */
    @PutMapping("/updateAppUser")
    public AjaxResult updateAppUser(@RequestBody  AppUser appUser) {
        String token = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(token)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        appUser.setOpenid(AppUser.getOpenid());
        appUserService.updateAppUser(appUser);
        appUser = appUserService.selectAppUserByOpenId(AppUser.getOpenid());
        redisCache.setCacheObject(Constants.XCX_TOKEN + appUser.getOpenid(), appUser, appexpireTime, TimeUnit.MINUTES);
        return AjaxResult.success(appUser);
    }

    /**
     * 根据token查询登录用户信息
     *
     * @return 结果
     */
    @GetMapping("/getAppUserInfo")
    public AjaxResult getAppUserInfo() {
        String token = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(token)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        return AjaxResult.success(AppUser);
    }

    /**
     * 根据token查询登录用户信息
     *
     * @return 结果
     */
    @GetMapping("/weixinAccount")
    public AjaxResult weixinAccount() {
        String token = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(token)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        return AjaxResult.success(AppUser);
    }

    /**
     * 根据token查询下级用户列表
     *
     * @return 结果
     */
    @GetMapping("/getAppUserList")
    public TableDataInfo getAppUserList() {
        String token = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        AppUser  params=new AppUser();
        if(AppUser.getRole().equals("0") || AppUser.getRole().equals("1")){
            params.setAplUuid(AppUser.getAplUuid());
        }else if(AppUser.getRole().equals("2")){
            params.setOpenid(AppUser.getOpenid());
        }
        startPage();
        return getDataTable(appUserService.selectAppUserByOpenIdList(AppUser));
    }

    /**
     * 根据token查询下级用户流水
     *
     * @return 结果
     */
    @GetMapping("/getAppUserHistory")
    public TableDataInfo getAppUserHistory() {
        String token = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        AppUserHistory AppUserHistory=new AppUserHistory();
        if(AppUser.getRole().equals("0") || AppUser.getRole().equals("1")){
            AppUserHistory.setAplUuid(AppUser.getAplUuid());
        }else if(AppUser.getRole().equals("2")){
            AppUserHistory.setFatherId(AppUser.getOpenid());
            AppUserHistory.setOpenId(AppUser.getOpenid());
        }else{
            AppUserHistory.setOpenId(AppUser.getOpenid());
        }
        startPage();
        return getDataTable( appUserHistoryService.selectAppUserFatherIdHistoryList(AppUserHistory));
    }

    /**
     * 根据token查询下级用户流水
     *
     * @return 结果
     */
    @GetMapping("/getAppUserHistoryLocal")
    public TableDataInfo getAppUserHistoryLocal() {
        String token = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + token);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(token);
            redisCache.setCacheObject(Constants.XCX_TOKEN + token, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        AppUserHistory AppUserHistory=new AppUserHistory();
        AppUserHistory.setOpenId(AppUser.getOpenid());
        startPage();
        return getDataTable( appUserHistoryService.selectAppUserFatherIdHistoryList(AppUserHistory));
    }

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 根据token发送授权
     * @return 结果
     */
    @PutMapping("/getAuDouYin")
    public AjaxResult getAuDouYin(@RequestBody  DouyinVo douyinVo) {
        String tokenId = ServletUtils.getHeaderString("token");
        //String tokenId="oZC4K5IF_j9Tpvx7c_4a9l9qkJtI";
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + AppUser.getAplUuid());
        if(StringUtils.isNull(douyinApl)){
            return error("应用不存在");
        }
        String result=HttpUtils.sendPost(YUMING+"/queryDouyinInfo",JSONObject.toJSONString(douyinVo),douyinApl.getAppId(),douyinApl.getAppSecret(),AppUser.getOpenid());
        if(StringUtils.isNull(result)){
            return  error("服务器断开连接");
        }
        JSONObject JSON=JSONObject.parseObject(result);
        if(JSON.getIntValue("code")==200){
            return new AjaxResult(JSON.getIntValue("code"),JSON.getString("code"),JSON.getJSONObject("data"));
        }else{
            return  error(result);
        }
    }


    /**
     * 下单
     * @return 结果
     */
    @PutMapping("/creatProjectNew")
    public AjaxResult creatProjectNew(@RequestBody CreateProjectVo createProjectVo) {
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + AppUser.getAplUuid());
        if(StringUtils.isNull(douyinApl)){
            return error("应用不存在");
        }
        String result=HttpUtils.sendPost(YUMING+"/xcxCreatProjectNew",JSONObject.toJSONString(createProjectVo),douyinApl.getAppId(),douyinApl.getAppSecret(),AppUser.getOpenid());
        if(StringUtils.isNull(result)){
            return  error("服务器断开连接");
        }
        JSONObject JSON=JSONObject.parseObject(result);
        if(JSON.getIntValue("code")==200){
            return new AjaxResult(JSON.getIntValue("code"),JSON.getString("code"),JSON.getJSONObject("data"));
        }else{
            return  error(result);
        }
    }

    @ApiOperation("生成流水")
    @PostMapping("/putHistory")
    public AjaxResult putHistory(@RequestBody AppUserHistory appUserHistory)
    {
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        appUserHistory.setOpenId(AppUser.getOpenid());
        return success(appUserHistoryService.insertAppUserHistory(appUserHistory));
    }

    @ApiOperation("微信下单")
    @GetMapping("/addMoneyFromWechat/{amount}")
    public AjaxResult addMoneyFromWechat(@PathVariable("amount") @ApiParam(value = "下单金额", required = true) Long amount) throws Exception
    {
        String tokenId = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        return appUserService.addMoneyFromWechat(AppUser, amount);
    }

    @ApiOperation("关闭订单")
    @GetMapping("/closeOrder/{out_trade_no}")
    public AjaxResult closeOrder(@PathVariable("out_trade_no") @ApiParam(value = "订单号", required = true) String out_trade_no) throws Exception
    {
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        return appUserService.closeOrder(AppUser,out_trade_no);
    }


    /**
     * 查询当前登录人,订单列表分页
     */
    @GetMapping("/projectList")
    public TableDataInfo projectList()
    {
        String tokenId = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        startPage();
        Project project=new Project();
        project.setThirdOrderId(AppUser.getOpenid());
        return getDataTable(appUserService.selectProjectList(project));
    }


    /**
     * 查询当前登录人下级列表分页
     */
    @GetMapping("/projectNextList")
    public TableDataInfo projectNextList(AppUser params)
    {
        String tokenId = ServletUtils.getHeaderString("token");
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        if(AppUser.getRole().equals("0") || AppUser.getRole().equals("1")){
            params.setAplUuid(AppUser.getAplUuid());
        }else if(AppUser.getRole().equals("2")){
            if(StringUtils.isNull(params.getOpenid())){
                params.setFatherId(AppUser.getOpenid());
            }
        }else{
            if(StringUtils.isNull(params.getOpenid())){
                params.setOpenid(AppUser.getOpenid());
            }
        }
        List<AppUser> sysuserList=appUserService.selectAppUserByOpenIdList(AppUser);
        sysuserList.add(AppUser);
        List<Project> projectList=new ArrayList<>();
        for (AppUser appUser : sysuserList) {
            Project project=new Project();
            project.setThirdOrderId(appUser.getOpenid());
            projectList.addAll(appUserService.selectProjectList(project));
        }
        return getDataTable(projectList);
    }

    /**
     * 根据token查询商品列表以及会员价格
     * @return 结果
     */
    @GetMapping("/goodsList")
    public AjaxResult goodsList() {
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + AppUser.getAplUuid());
        if(StringUtils.isNull(douyinApl)){
            return error("应用不存在");
        }
        String merchantId=appUserService.selectMerchant(douyinApl.getAppId());
        if(StringUtils.isNull(merchantId)){
            return  error("匹配商户商品失败");
        }
        Goods good=new Goods();
        good.setMerchantId(merchantId);
        good.setOpenid(AppUser.getOpenid());
        return AjaxResult.success(goodsService.selectGoodsListByUser(good));
    }


    @ApiOperation("商品详情")
    @GetMapping("/goodsInfo/{goodId}")
    public AjaxResult goodsInfo(@PathVariable("goodId") @ApiParam(value = "商品ID", required = true) String goodId)
    {
        //查询商品列表
        Goods good=goodsService.selectGoodsByGoodId(goodId);
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return AjaxResult.error(502,"token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        //根据登录人AccountId和goodId查询对应修改后的最终单价
        DouyinBasicmemberPrice douyinBasicmemberPrice=new DouyinBasicmemberPrice();
        douyinBasicmemberPrice.setAccountId(AppUser.getOpenid());
        douyinBasicmemberPrice.setGoodId(goodId);
        List<DouyinBasicmemberPrice> basePriList=douyinBasicmemberPriceService.selectDouyinBasicmemberPriceList(douyinBasicmemberPrice);
        if(basePriList.size()>0){
            //基础会员最终的商品单价
            good.setBasePrice(basePriList.get(0).getBasePrice());
        }
        return AjaxResult.success(good);
    }

    /**
     * 商品列表中---修改基础会员对应商品单价
     */
    @PutMapping("/updateBasicMeberPrice")
    public AjaxResult updateBasicMeberPrice(@RequestBody DouyinBasicmemberPrice douyinBasicmemberPrice)
    {
        String tokenId = ServletUtils.getHeaderString("token");
        if (StringUtils.isEmpty(tokenId)) {
            return error("token不能为空");
        }
        AppUser AppUser = redisCache.getCacheObject(Constants.XCX_TOKEN + tokenId);
        if (StringUtils.isNull(AppUser)) {
            AppUser = this.appUserService.selectAppUserByOpenId(tokenId);
            redisCache.setCacheObject(Constants.XCX_TOKEN + tokenId, AppUser, appexpireTime, TimeUnit.MINUTES);
        }
        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + AppUser.getAplUuid());
        if(StringUtils.isNull(douyinApl)){
            return error("应用不存在");
        }
        AppUser baseUser= this.appUserService.selectAppUserByOpenId(douyinBasicmemberPrice.getOpenid());
        //基础会员信息的父级accountId，如果不是当前登录人的accountId,则不然执行下方操作。
        if(!AppUser.getOpenid().equals(baseUser.getFatherId())){
            return  warn("该基础用户,非该登录用户的会员");
        }

        //根据用户的merchantID查询商品列表,用于判断修改的单价是否低于高级会员单价，如果低于，则不让操作
        Goods goods=goodsService.selectGoodsByGoodId(douyinBasicmemberPrice.getGoodId());
        if(goods.getGoodsPrice().compareTo(douyinBasicmemberPrice.getBasePrice())>0){
            return warn("高级会员价格低于基础会员价格，请重新调整！");
        }

        List<DouyinBasicmemberPrice> list=douyinBasicmemberPriceService.selectDouyinBasicmemberPriceList(douyinBasicmemberPrice);
        int flag=0;
        if(list.size()>0){
            douyinBasicmemberPrice.setId(list.get(0).getId());
            flag=douyinBasicmemberPriceService.updateDouyinBasicmemberPrice(douyinBasicmemberPrice);
        }else{
            flag=douyinBasicmemberPriceService.insertDouyinBasicmemberPrice(douyinBasicmemberPrice);
        }
        return toAjax(flag);
    }

}
